package model;

import javax.jms.*;
import java.util.List;
import java.util.ListIterator;

import entity.TableRecord;
import org.hibernate.*;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import util.HibernateUtil;
import util.MessagingUtil;
import util.TableRecordBuilder;

/*
 * Sends given Message to Queue,
 * receives a Reply and returns it to the Manager
 */

public class Handler implements Runnable {
    private List<TableRecord> records;
    //private Integer count;
    private static final Logger logger = LoggerFactory.getLogger(Handler.class);

    // Hibernate session
    private Session session;

    // JMS
    public final static String QUEUE="TestQ";


    public Handler(List<TableRecord> records) {
        this.records = records;
        //this.count = records.size();
    }



    @Override
    public void run() {
        logger.info("Inside Handler!");

        MessagingUtil util = new MessagingUtil();

        Queue staticQueue = util.createQueue(QUEUE);
        QueueSender sender = util.createSender(staticQueue);


        Queue dynamicQueue = util.createTempQueue();
        QueueReceiver receiver = util.createReceiver(dynamicQueue);

        util.startConnection();

        try {
            String reply;

            ListIterator<TableRecord> iterator = records.listIterator();

            while(iterator.hasNext()) {
                TableRecord record = iterator.next();
                util.sendMessage(sender, record.getMessage(), dynamicQueue);
                reply = util.receiveMessage(receiver);
                TableRecordBuilder builder = new TableRecordBuilder();
                builder.clone(record);
                builder.addReply(reply);
                builder.addStatus("old");
                record = builder.getTableRecord();
                iterator.set(record);
            }
        } finally {
            try {
                util.closeSender(sender);
            } finally {
                try {
                    util.closeReceiver(receiver);
                } finally {
                    util.closeSession();
                }
            }
        }
        logger.info("All replies were received.");

        try {
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            for(TableRecord record : records) {
                session.update(record);
            }
            session.getTransaction().commit();
        } finally {
            if(session != null  && session.isOpen()) {
                session.close();
            }
        }
        logger.info("All replies were recorded to database.");

    }
}
